/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022.
 * Description: irq bypass
 * Author: lilinjie8 <lilinjie8@huawei.com>
 * Create: 2022-01-24
 */

#ifndef HPVISOR_ARM64_IRQBYPASS_H
#define HPVISOR_ARM64_IRQBYPASS_H
#include "../../virt/hpvisor/irqbypass.h"

#define VTIMER_IRQ 27
#define HPVISOR_HCR_IRQ_BYPASS ~(HCR_FMO | HCR_IMO)

#ifdef CONFIG_FIQ_GLUE
extern void fiq_el1_trigger(void);
extern char __cacheline_aligned nmi_virt_ctx_base[];
#endif

void hpvisor_gic_handle_irq(u32 irqnr);
extern void hpvisor_gic_show_gicr_state(struct kvm_vcpu *vcpu, bool enter);
extern void hpvisor_gic_eoi_activated(void *mask);
extern void hpvisor_gic_set_state(u32 hwirq, enum irqchip_irq_state which, bool val);
extern void hpvisor_gic_get_state(u32 hwirq, enum irqchip_irq_state which, bool *val);

int hpvisor_vcpu_irq_data_init(struct kvm_vcpu *vcpu);
int hpvisor_vcpu_handle_hvc_call(const struct kvm_vcpu *vcpu);
void hpvisor_vcpu_handle_hvc_early(const struct kvm_vcpu *vcpu);
void hpvisor_vcpu_set_userspace_retval(struct kvm_vcpu *vcpu);
void hpvisor_vcpu_inject_irq(struct kvm_vcpu *vcpu);

static inline void hpvisor_gic_enable_vtimer(const struct kvm_vcpu *vcpu)
{
	if (likely(vcpu->gic_mode == HPVISOR_IRQ_BYPASS))
		hpvisor_gic_set_state(VTIMER_IRQ, IRQCHIP_STATE_MASKED, false);
}

static inline void hpvisor_gic_disable_vtimer(const struct kvm_vcpu *vcpu)
{
	if (likely(vcpu->gic_mode == HPVISOR_IRQ_BYPASS))
		hpvisor_gic_set_state(VTIMER_IRQ, IRQCHIP_STATE_MASKED, true);
}
#endif
